import { initComputed } from "./computed"
import { observe } from "./observe"

export function initState(vm) {
  const opts = vm.$options
  if (opts.data) {
    initData(vm)
  }

  if (opts.computed) {
    initComputed(vm)
  }

  if (opts.watch) {
    initWatch(vm)
  }
}

function initData(vm) {
  let data = vm.$options.data
  data = typeof data === "function" ? data.call(vm) : data

  vm._data = data
  observe(data)

  for (let key in data) {
    proxy(vm, "_data", key)
  }
}

// 把数据代理到vm身上，可能使用 vm.xxx（this.xxx） 来访问
function proxy(vm, target, key) {
  Object.defineProperty(vm, key, {
    get() {
      return vm[target][key]
    },
    set(newValue) {
      vm[target][key] = newValue
    }
  })
}

// 实现watch, 只写了字符串和函数式写法，对象写法没有实现
function initWatch(vm) {
  let watch = vm.$options.watch // watch有很多种写法
  for (let key in watch) {
    const handler = watch[key]
    if (Array.isArray(handler)) {
      for (let i = 0; i < handler.length; i++) {
        createWatcher(vm, key, handler[i])
      }
    } else {
      createWatcher(vm, key, handler)
    }
  }
}
function createWatcher(vm, key, handler) {
  if (typeof handler === "string") {
    handler = vm[key]
  }
  return vm.$watch(key, handler)
}
